﻿<!DOCTYPE html>
<html>
<head>
<!----------------------------------------------------------

	Copyright (c) 2015-2018 Jean-Marc VIGLINO,
	released under CeCILL-B (french BSD like) licence: http://www.cecill.info/

------------------------------------------------------------>
	<title>ol-ext: style chart</title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

	<meta name="description" content="ol.style.Chart is an image style to draw statistical graphics (bar or pie charts) on a map." />
	<meta name="keywords" content="ol3, style, vector, statistic, chart, pie, animation" />

	<!-- jQuery -->
	<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>

	<!-- Openlayers -->
    <link rel="stylesheet" href="https://openlayers.org/en/latest/css/ol.css" />
	<script type="text/javascript" src="https://openlayers.org/en/latest/build/ol.js"></script>
	<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
	
	<!-- ol-ext -->
	<script type="text/javascript" src="../../dist/ol-ext.js"></script>

	<link rel="stylesheet" href="../style.css" />

</head>
<body >
	<a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>

	<a href="../../index.html">
		<h1>ol-ext: chart style + values</h1>
	</a>
	<p class="info">
		The <i>ol.style.Chart</i> is an image style to draw statistical graphics (bar or pie charts) on a map.
		<br/>
		This example show how to display values on a pie chart using a style function.
	</p>

	<!-- DIV pour la carte -->
	<div id="map" style="width:600px; height:400px;"></div>
	<div class="options">
		Select a feature to show its values.
	</div>
	
	<script type="text/javascript">
	// Layers
	var layer = new ol.layer.Tile({ source: new ol.source.Stamen({ layer: 'watercolor' }) });
		
	// The map
	var map = new ol.Map
		({	target: 'map',
			view: new ol.View
			({	zoom: 6,
				center: [166326, 5992663]
			}),
			layers: [layer]
		});

	// Style function
	var styleCache={};
	
	function getFeatureStyle (feature, sel)
	{	var k = $("#graph").val()+"-"+ $("#color").val()+"-"+(sel?"1-":"")+feature.get("data");
  		var style = styleCache[k];
		if (!style) 
		{	var radius = 15;
			// area proportional to data size: s=PI*r^2
			radius = 8* Math.sqrt (feature.get("sum") / Math.PI);
			var data = feature.get("data");
			radius *= (sel?1.2:1);
			// Create chart style
			style = [ new ol.style.Style(
				{	image: new ol.style.Chart(
					{	type: "pie", 
						radius: radius, 
						data: data, 
						rotateWithView: true,
						stroke: new ol.style.Stroke(
						{	color: "#fff",
							width: 2
						}),
					})
				})];

			// Show values on select
			if (sel)
			{	/*
				var sum = 0;
				for (var i=0; i<data.length; i++)
				{	sum += data[i];
				}
				*/
				var sum = feature.get("sum");
      
				var s = 0;
				for (var i=0; i<data.length; i++)
				{	var d = data[i];
      				var a = (2*s+d)/sum * Math.PI - Math.PI/2; 
					var v = Math.round(d/sum*1000);
					if (v>0)
      				{	style.push(new ol.style.Style(
						{	text: new ol.style.Text(
							{	text: (v/10)+"%", /* d.toString() */
          						offsetX: Math.cos(a)*(radius+3),
          						offsetY: Math.sin(a)*(radius+3),
								textAlign: (a < Math.PI/2 ? "left":"right"),
								textBaseline: "middle",
								stroke: new ol.style.Stroke({ color:"#fff", width:2.5 }),
								fill: new ol.style.Fill({color:"#333"})
							})
						}));
					}
					s += d;
				}
			}
		}
		styleCache[k] = style;
		return style;
	}

	// 30 random features with data: array of 4 values
	var ext = map.getView().calculateExtent(map.getSize());
	var features=[];
	for (var i=0; i<30; ++i)
	{	var n, nb=0, data=[];
		for (var k=0; k<4; k++) 
		{	n = Math.round(8*Math.random());
			data.push(n);
			nb += n;
		}
		features[i] = new ol.Feature(
			{	geometry: new ol.geom.Point([ext[0]+(ext[2]-ext[0])*Math.random(), ext[1]+(ext[3]-ext[1])*Math.random()]),
				data: data,
				sum: nb
			});
	}
	var vector = new ol.layer.Vector(
	{	name: 'Vecteur',
		source: new ol.source.Vector({ features: features }),
		// y ordering
		renderOrder: ol.ordering.yOrdering(),
		style: function(f) { return getFeatureStyle(f); }
	})

	map.addLayer(vector);

	// Control Select 
	var select = new ol.interaction.Select({
            style: function(f) { return getFeatureStyle(f, true); }
          });
	map.addInteraction(select);

	</script>
	
</body>
</html>